<template>
  <div class="system-dic-container layout-padding">
    <el-card shadow="hover" class="mb5" body-class="pa5">
      <el-row>
        <el-col :xs="24" :sm="8" :md="6" :lg="6" :xl="4" class="pa5">
          <el-input clearable v-model="filterText" placeholder="查询菜单" :prefix-icon="Search" />
        </el-col>
        <el-col :xs="24" :sm="6" :md="4" :lg="4" :xl="4" class="pa5">
          <el-select v-model="params.object_type" placeholder="选择类型" @change="onChangeType">
            <el-option label="按角色" :value="0" />
            <el-option label="按用户" :value="1" />
            <el-option label="全部用户" :value="9" />
          </el-select>
        </el-col>
        <el-col
          :xs="24"
          :sm="12"
          :md="8"
          :lg="8"
          :xl="6"
          class="pa5"
          v-if="params.object_type === 0"
        >
          <el-select
            clearable
            filterable
            v-model="params.object_id"
            placeholder="请选择角色"
            @change="onFetch"
          >
            <el-option
              v-for="(item, index) in roleItems"
              :key="index"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </el-col>
        <el-col
          :xs="24"
          :sm="12"
          :md="8"
          :lg="8"
          :xl="6"
          class="pa5"
          v-else-if="params.object_type === 1"
        >
          <el-tree-select
            clearable
            filterable
            :data="userItems"
            default-expand-all
            v-model="params.object_id"
            @change="onFetch"
            placeholder="请选择用户"
          />
        </el-col>
        <el-col :xs="24" :sm="8" :md="6" :lg="6" :xl="4" class="pa5">
          <el-button
            type="primary"
            :icon="Search"
            :loading="loading"
            @click="onFetch"
            class="ml-auto"
            :disabled="!params.object_id && params.object_type !== 9"
          >
            查询
          </el-button>
        </el-col>
      </el-row>
    </el-card>
    <div class="pa10 layout-padding-auto layout-padding-view">
      <el-scrollbar>
        <el-tree
          style="min-width: 600px; max-width: 850px"
          ref="treeRef"
          :data="items"
          :props="{
            children: 'children',
            label: 'title',
            value: 'id'
          }"
          node-key="id"
          default-expand-all
          :filter-node-method="filterNode"
        >
          <template #default="{ node, data }">
            <div class="custom-tree-node flex flex-grow">
              <span>{{ node.label }}</span>
              <el-tag v-if="data.is_hide" type="warning" class="ml10" size="small">隐藏</el-tag>
              <div
                v-if="!data.children.length"
                class="ml-auto mr20 flex align-center"
                @click.stop=""
              >
                <el-checkbox
                  v-model="data.free_data_range"
                  label="全部"
                  border
                  size="small"
                  class="mr10"
                  @change="onSave(data)"
                />
                <el-button
                  v-for="(item, index) in data.dataRanges"
                  :key="index"
                  :type="item.data_id.length ? 'primary' : 'info'"
                  size="small"
                  class="ml3"
                  plain
                  @click="onAction(data, item)"
                >
                  {{ item.data_type_name }} {{ item.data_id.length }}
                </el-button>
                <el-button
                  size="small"
                  class="ml5"
                  :type="copyId === data.id ? 'primary' : ''"
                  @click="copyId = data.id"
                >
                  复制
                </el-button>
                <el-button
                  size="small"
                  class="ml5"
                  :disabled="!copyId || copyId === data.id"
                  @click="onPaste(data)"
                  >粘贴
                </el-button>
                <el-button size="small" class="ml0" text type="danger" @click="onClear(data)">
                  清空
                </el-button>
              </div>
            </div>
          </template>
        </el-tree>
        <div style="height: 100px; width: 100%"></div>
      </el-scrollbar>
    </div>
    <ConfigureUsers ref="userRef" title="配置用户" @change="onSelectConfig" />
    <ConfigureDeps ref="depRef" title="配置部门" @change="onSelectConfig" />
    <ConfigureCorps ref="corpRef" title="配置公司" @change="onSelectConfig" />
  </div>
</template>

<script setup lang="ts" name="systemPermission">
import { defineAsyncComponent, onMounted, reactive, ref, watch } from 'vue'
import { useBaseRoleApi } from '@/api/base/role'
import { useBasePermissionApi } from '@/api/base/permission'
import { useBaseApi } from '@/api/base'
import { clone, findTree, toArrayTree } from 'xe-utils'
import { Search } from '@element-plus/icons-vue'
import { useI18n } from 'vue-i18n'
import type { BaseDataRange, BaseGetPermissionsType } from '@/api/base/permission'

const ConfigureUsers = defineAsyncComponent(() => import('@/components/custom/ConfigureUsers.vue'))
const ConfigureDeps = defineAsyncComponent(() => import('@/components/custom/ConfigureDeps.vue'))
const ConfigureCorps = defineAsyncComponent(() => import('@/components/custom/ConfigureCorps.vue'))

// 定义变量内容
const { search_all_users } = useBaseApi()
const { GetBaseRoleList } = useBaseRoleApi()
const { GetDataRange, SetDataRange } = useBasePermissionApi()

interface UserRoleType {
  id: string
  name: string
  descript: string
  users_id: string[]
  userse_name: string[]
  user_count: number
}

const { t } = useI18n()
const treeRef = ref()
const userRef = ref()
const depRef = ref()
const corpRef = ref()
const loading = ref(false)
const roleItems = ref<UserRoleType[]>([])
const userItems = ref<UserRoleType[]>([])
const copyId = ref('')
const params = reactive({
  cat: 0,
  object_type: 0, // 0 角色 1 用户
  object_id: '' // 用户或角色ID
})
const items = ref<BaseGetPermissionsType[]>([])
const currentRow = ref<BaseGetPermissionsType | undefined>()
const currentData = ref<BaseDataRange | undefined>()
const filterText = ref('')
const data_types: TypedAny = {
  0: '用户',
  1: '部门',
  2: '公司',
  99: '全部'
}

const filterNode = (value: string, data: any) => {
  if (!value) return true
  return data.title.includes(value)
}

/**
 * 类型改变
 */
const onChangeType = () => {
  params.object_id = params.object_type === 9 ? 'ALL' : ''
  if (params.object_type === 9) {
    onFetch()
  } else {
    items.value = []
  }
}

// 查询菜单
const onFetch = () => {
  loading.value = true
  GetDataRange(params)
    .then(({ data }) => {
      const list = data.map((v) => {
        v.business.title = t(v.business.title)
        v.business.dataRanges = v.dataRanges.map((v) => {
          v.data_type_name = data_types[String(v.data_type)] || ''
          return v
        })
        v.business.req = v.req
        return v.business
      })
      items.value = toArrayTree(list, { parentKey: 'pid', sortKey: 'idx' })
    })
    .finally(() => (loading.value = false))
}

// 保存
const onSave = async (row: BaseGetPermissionsType) => {
  loading.value = true
  const params = clone(row, true)
  SetDataRange({
    business: params,
    dataRanges: params.dataRanges,
    req: params.req
  }).finally(() => (loading.value = false))
}

/**
 * 配置
 * @param row
 * @param data
 */
const onAction = (row: BaseGetPermissionsType, data: BaseDataRange) => {
  currentRow.value = row
  currentData.value = data
  if (data.data_type === 0) {
    userRef.value.open(true, data.data_id)
  } else if (data.data_type === 1) {
    depRef.value.open(true, data.data_id)
  } else if (data.data_type === 2) {
    corpRef.value.open(true, data.data_id)
  }
}

/**
 * 粘贴
 * @param row
 */
const onPaste = (row: BaseGetPermissionsType) => {
  const item = findTree(items.value, (item) => item.id === copyId.value)
  if (item && item.item) {
    row.free_data_range = item.item.free_data_range
    row.dataRanges?.forEach((v) => {
      const data = item.item.dataRanges?.find((f) => f.data_type === v.data_type)
      if (data) {
        v.data_id = data.data_id.map((v) => v)
      }
    })
    onSave(row)
  }
}

/**
 * 清空
 * @param row
 */
const onClear = (row: BaseGetPermissionsType) => {
  row.free_data_range = false
  row.dataRanges?.forEach((v) => {
    v.data_id = []
  })
  onSave(row)
}

/**
 * 选中
 * @param userIds
 */
const onSelectConfig = (userIds: string[]) => {
  if (currentData.value) {
    currentData.value.data_id = userIds
    if (currentRow.value) onSave(currentRow.value)
  }
}

/**
 * 查询列表
 */
const onFetchDefault = () => {
  GetBaseRoleList().then(({ data }) => {
    roleItems.value = data
    if (data.length) {
      params.object_id = data[0].id
      onFetch()
    }
  })
  search_all_users({
    status_dis: 0,
    status_leave: 0
  }).then(({ data }) => {
    const { deps, users } = data
    users.forEach((user) => {
      user.isUser = true
      user.value = user.id
      user.label = user.name
    })
    deps.forEach((dep) => {
      const items = users.filter((user) => user['dep_id'] === dep.id)
      dep.value = dep.id
      dep.label = `${dep.name}[${items.length}人]`
      dep.disabled = !deps.some((s) => s.pid === dep.id) && !items.length
      items.forEach((user) => {
        user.pid = dep.id
      })
    })
    userItems.value = toArrayTree(deps.concat(users), { parentKey: 'pid' })
  })
}

watch(filterText, (val) => {
  treeRef.value!.filter(val)
})

// 页面加载时
onMounted(() => {
  onFetchDefault()
})
</script>
